﻿using System;
using System.Collections.Generic;
using System.Globalization;
using GammaJul.ReSharper.GammaXaml.Highlightings.Xaml;
using JetBrains.Annotations;
using JetBrains.ReSharper.Daemon;
using JetBrains.ReSharper.Feature.Services.Bulbs;
using JetBrains.ReSharper.Intentions.Extensibility;
using JetBrains.ReSharper.Intentions.Extensibility.Menu;
using JetBrains.Util;

namespace GammaJul.ReSharper.GammaXaml.QuickFixes.Xaml {

	/// <summary>
	/// A quick fix that presents a group of <see cref="UseDefinitionItem"/>, used to change the values of a row or column.
	/// </summary>
	[QuickFix]
	public class UseDefinitionFix : IQuickFix {
		private readonly GridDefinitionValueOutOfRangeHighlighting _highlighting;

		public void CreateBulbItems(BulbMenu menu, Severity severity) {
			ReadOnlyList<string> defSizes = _highlighting.GridDefinitionSizes;

			BulbGroup group = menu.GetOrCreateGroup(AnchorsForBulbMenuGroups.QuickFixesAnchor);
			
			// only one fix, arrange it and we're done
			if (defSizes.Count == 1) {
				menu.ArrangeQuickFix(CreateQuickFix(defSizes, 0), severity);
				return;
			}

			// in case of multiple fixes, add the nearest row fix to the top-level menu and put others in a sub menu
			int currentValue;
			if (!Int32.TryParse(_highlighting.ValueToken.GetText(), NumberStyles.None, CultureInfo.InvariantCulture, out currentValue))
				currentValue = -1;

			if (currentValue < 0) {
				menu.ArrangeQuickFix(CreateQuickFix(defSizes, 0), severity);
				BulbMenuItem fixMenu = group.GetOrCreateSubmenu(GridQuickFixBulbMenu.DefinitionFixDescription);
				fixMenu.Submenu.ArrangeQuickFixes(CreateQuickFixes(defSizes, 1, defSizes.Count - 1, severity));
			}
			
			else {
				menu.ArrangeQuickFix(CreateQuickFix(defSizes, defSizes.Count - 1), severity);
				BulbMenuItem fixMenu = group.GetOrCreateSubmenu(GridQuickFixBulbMenu.DefinitionFixDescription);
				fixMenu.Submenu.ArrangeQuickFixes(CreateQuickFixes(defSizes, 0, defSizes.Count - 1, severity));
			}
		}

		[NotNull]
		private UseDefinitionItem CreateQuickFix([NotNull] IList<string> defSizes, int index) {
			return new UseDefinitionItem(_highlighting, index, defSizes[index]);
		}

		[NotNull]
		private IEnumerable<Pair<IBulbAction, Severity>> CreateQuickFixes([NotNull] IList<string> defSizes, int start, int count, Severity severity) {
			var items = new Pair<IBulbAction, Severity>[count];
			for (int i = start; i < start + count; ++i)
				items[i - start] = Pair.Of((IBulbAction) CreateQuickFix(defSizes, i), severity);
			return items;
		}

		public bool IsAvailable(IUserDataHolder cache) {
			return _highlighting.IsValid();
		}

		public UseDefinitionFix([NotNull] GridDefinitionValueOutOfRangeHighlighting highlighting) {
			if (highlighting == null)
				throw new ArgumentNullException("highlighting");
			_highlighting = highlighting;
		}
	}

}